package com.ekalenchuk.module.service.user;

import java.util.EnumSet;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.social.facebook.api.FacebookProfile;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ekalenchuk.module.dao.user.UserDao;
import com.ekalenchuk.module.domain.user.User;
import com.ekalenchuk.module.dto.UserDetailsInfo;
import com.ekalenchuk.module.dto.registration.UserRegistrationDto;
import com.ekalenchuk.module.dto.session.UserSession;
import com.ekalenchuk.module.enums.Authority;
import com.ekalenchuk.module.exception.entity.NotFoundException;
import com.ekalenchuk.module.service.secutiry.CustomAuthenticationProvider;
import com.ekalenchuk.module.utils.ConverterUtils;

@Service
public class UserServiceImpl implements UserService {
	
	private static final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);

	@Autowired
	private UserDao userDao;
	
	@Autowired
	private CustomAuthenticationProvider customAuthenticationProvider;
	
    /**
     * Return user from DB by unique id;
     *
     * @param id user id
     * @return user
     */

    @Transactional
    public User getUser(Long id) {
        return userDao.getById(id);
    }
    
    public UserDetailsInfo getUserDetails(String login) throws NotFoundException {
    	User user = getUserByLogin(login);
    	UserDetailsInfo userDetailsDTO = new UserDetailsInfo();
    	userDetailsDTO.setId(user.getId());
    	userDetailsDTO.setIdentificationName(user.getLogin());
    	return userDetailsDTO;
    	
    }

    /**
     * Search user in DB by login.
     *
     * @param login unique user name
     * @return user
     * @throws NotFoundException 
     */
    @Transactional
    public User getUserByLogin(String login) throws NotFoundException {
        return userDao.getUserByLogin(login);
    }

    /**
     * Return all users from DB.
     *
     * @return user list
     */
    @Transactional
    public List<User> getUsers() {
        return userDao.findAll();
    }

    @Transactional
	public User registrate(final UserRegistrationDto profile) {
    	User newUser = ConverterUtils.toUser(profile);
    	//TODO implement
    	newUser = userDao.save(newUser);
    	return newUser;
	}

    @Transactional
	public void login(FacebookProfile profile, UserSession userSession) throws NotFoundException {
		User user = getUserByFacebookId(Long.parseLong(profile.getId()));
		if(user == null) {
			UserRegistrationDto dto = ConverterUtils.toUserRegistrationDTO(profile);
			user = registrate(dto);
		}
		login(userSession, user);
	}
    
    @Transactional
    public User getUserByFacebookId(final Long fbId) throws NotFoundException {
    	return userDao.getUserByFacebookId(fbId);
    }
    
    private void login(final UserSession userSession, final User user) {
		ConverterUtils.toUserSession(userSession, user);
		userSession.setLoggedIn(true);
		UserDetailsInfo userDTO = new UserDetailsInfo();
        userDTO.setAuthority(EnumSet.of(Authority.USER));
        userDTO.setUserSession(userSession);
        userDTO.setPassword(user.getPassword());
        userDTO.setIdentificationName(user.getLogin());
        customAuthenticationProvider.trust(userDTO);
	}


}
